package org.apache.nutch.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import cn.data.SysConf;

/**
 * Servlet implementation class NutchControllerSerlet
 */
public class NutchControllerServlet extends HttpServlet
{

	private static Logger log = Logger.getLogger(NutchControllerServlet.class);

	protected ServletConfig config = null;
	
	private SysConf sysConf = null;
	
	private String nutchHome = null;
	
	private String cloneNutchHome = null;
	
	private String keywordsFileName = null;
	
	private File keywordsFile = null;
	
	private String urlSeedsFileName = null;
	
	private File urlSeedsFile = null;
	
	private WebApplicationContext ctx = null; 
	
	private static Set<String> nutchIdList = new HashSet<String>();
	
	private static String contextRealPath = null;
	
	@Override
	public void init(ServletConfig config) throws ServletException
	{
		super.init(config);
		
		ctx = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
		sysConf = (SysConf) ctx.getBean("sysConf");
		nutchHome = sysConf.getNutchHome();
		keywordsFileName = sysConf.getKeywordsFileName();
		if(StringUtils.isNotBlank(nutchHome) && StringUtils.isNotBlank(keywordsFileName)) 
		{
			keywordsFile = new File(nutchHome, keywordsFileName); 
		}

		urlSeedsFileName = sysConf.getUrlSeedsFileName();
		if(StringUtils.isNotBlank(nutchHome) && StringUtils.isNotBlank(urlSeedsFileName)) 
		{
			urlSeedsFile = new File(nutchHome, urlSeedsFileName); 
		}
		contextRealPath = config.getServletContext().getRealPath("/");
		
		if(config.getServletContext().getAttribute("spiderList") == null) {
			config.getServletContext().setAttribute("spiderList", nutchIdList);
		}
	}

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public NutchControllerServlet()
	{
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		doPost(request, response);
	}
	
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		
		
		String action = request.getParameter("action");
		String nutchId = request.getParameter("id");
		
		// judge the action
		if(action.equalsIgnoreCase("stop"))
		{
			stopNutch(request.getSession().getServletContext(), nutchId);
//			deletefile("webapps/webcrawl/" + nutchNameTemp);
//			spiderPath.getNutchName().remove(nutchNameTemp);
//			response.sendRedirect("/index.jsp");
			return;
		}
		else if (action.equalsIgnoreCase("start") && !StringUtils.isBlank(nutchId))
		{
//			deletefile("webapps/webcrawl/nutch");
			
			//kao bei crawl wen jian jiad
			if(nutchIdList.contains(nutchId)) {
				log.warn("id exists:" + nutchId);
				return;
			}
			nutchIdList.add(nutchId);
		    
			cloneNutchHome = contextRealPath + "/" + nutchId;
			
			log.info("starting copy from:" + nutchHome + " to: " + cloneNutchHome);
			boolean bol = copyFilesToWebapps(nutchHome, cloneNutchHome);
			if(bol == true)
				log.info("copy finish!!");
			
			// chu li searchKeywordList
			String newKeywords = request.getParameter("searchKeywordList");
			if(!StringUtils.isEmpty(newKeywords)) 
			{
				// just over write keywords config file using new keywords
				FileWriter fw = new FileWriter(cloneNutchHome + "/classes/keywords.txt");
				IOUtils.copy(new StringReader(newKeywords), fw);
				IOUtils.closeQuietly(fw);
				log.info("keyword finish!!");
			}
			
			// chu li url seeds
			String newUrlSeeds = request.getParameter("searchURLList");
			if(!StringUtils.isEmpty(newUrlSeeds)) 
			{
				// just over write keywords config file using new keywords
//				FileWriter fw = new FileWriter(urlSeedsFile);
				FileWriter fw = new FileWriter(cloneNutchHome + "/seeds");
				IOUtils.copy(new StringReader(newUrlSeeds), fw);
				IOUtils.closeQuietly(fw);
				log.info("url seeds finish!!");
			}	
			
			// begin crawl	
			startNutch(request.getSession().getServletContext(), nutchId);
//			request.getRequestDispatcher("/urls.jsp").forward(request, response);
			return;

		}
	}
	
	public boolean deletefile(String delpath)
	{
		File file = new File(delpath);
		if (!file.isDirectory())
		{
			file.delete();
		}
		else if (file.isDirectory())
		{
			String[] filelist = file.list();
			for (int i = 0; i < filelist.length; i++)
			{
				File delfile = new File(delpath + "\\" + filelist[i]);
				if (!delfile.isDirectory())
					delfile.delete();
				else if (delfile.isDirectory())
					deletefile(delpath + "\\" + filelist[i]);
			}
			file.delete();
		}
		return true;
	}
	
	public boolean copyFilesToWebapps(String NutchPathOld, String NutchWebappsPathNew)
	{
		// TODO Auto-generated method stub
		if((new File(NutchWebappsPathNew)).mkdirs() == true)
		{ 
			File[] file=(new File(NutchPathOld)).listFiles(); 
			for(int i = 0; i < file.length; i++)
			{ 
				if(file[i].isFile())
				{
					FileInputStream input;
					try
					{
						input = new FileInputStream(file[i]);
						FileOutputStream output = new FileOutputStream(NutchWebappsPathNew + "/" + file[i].getName()); 
						byte[] b = new byte[1024*5]; 
						int len; 
						while((len = input.read(b)) != -1)
						{ 
							output.write(b,0,len);
						} 
						output.flush();
						output.close();
						input.close();
					}
					catch (FileNotFoundException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					catch (IOException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					} 
				}
				else if(file[i].isDirectory())
				{ 
					copyFilesToWebapps(NutchPathOld + "/" + file[i].getName(), NutchWebappsPathNew + "/" + file[i].getName()); 
				}
			}
			return true;
		}
		else
		{
			deletefile(NutchWebappsPathNew);
			copyFilesToWebapps(NutchPathOld, NutchWebappsPathNew);
		}
		return true;
	}

	private void startNutch(ServletContext context, String nutchId)
	{
		
		Thread startThread = new Thread(new NutchStarter(context, cloneNutchHome, sysConf, nutchId));
		startThread.start();
	}

	private void stopNutch(ServletContext context, String nutchId)
	{
		NutchEventDispatcher eventDispatcher = new NutchEventDispatcher();
		NutchProcessDestroyer pd = (NutchProcessDestroyer) context.getAttribute(nutchId);
		eventDispatcher.addListener(pd);
		eventDispatcher.fireEvent(new NutchEvent("stop"));
	}

}
